package rbac

import (
	"context"
	"fmt"
	"gitee.com/bobo-rs/idea-space-framework/framework/dao"
	"gitee.com/bobo-rs/idea-space-framework/framework/model"
	"gitee.com/bobo-rs/idea-space-framework/framework/model/entity"
	"gitee.com/bobo-rs/idea-space-framework/pkg/exception"
	"gitee.com/bobo-rs/idea-space-framework/pkg/utils"
	"github.com/gogf/gf/v2/frame/g"
)

// SaveAdminDepartment 保存管理员关联部门数据
func (r *sRbac) SaveAdminDepartment(ctx context.Context, adminId uint, departId ...uint) error {
	if len(departId) == 0 {
		return exception.New(`缺少部门ID`)
	}

	// 处理管理员关联部门数据
	adds := make([]entity.AdminDepartment, 0)
	for _, pid := range departId {
		adds = append(adds, entity.AdminDepartment{
			AdminId:  adminId,
			DepartId: pid,
		})
	}

	// 移除之前绑定
	if r.CheckAdminDepartByAid(ctx, adminId) {
		_, err := dao.AdminDepartment.Ctx(ctx).
			Where(dao.AdminDepartment.Columns().AdminId, adminId).
			Delete()
		if err != nil {
			return exception.New(`移除部门失败，请重试`)
		}
	}

	// 添加部门信息
	_, err := dao.AdminDepartment.Ctx(ctx).Insert(adds)
	if err != nil {
		return exception.New(`授权绑定部门失败`)
	}
	return nil
}

// GetDepartPeopleNumByDepartId 通过部门ID-获取部门人数MAP
func (r *sRbac) GetDepartPeopleNumByDepartId(ctx context.Context, departId ...uint) (map[uint]uint, error) {
	if len(departId) == 0 {
		return nil, exception.New(`缺少部门ID`)
	}

	// 初始化
	var (
		peopleRows []model.DepartmentPeopleNumItem
		peopleMap  = make(map[uint]uint)
	)

	// 获取部门人数
	err := dao.AdminDepartment.Ctx(ctx).
		Where(dao.AdminDepartment.Columns().DepartId, departId).
		Fields(fmt.Sprintf(`count(*) total, %s`, dao.AdminDepartment.Columns().DepartId)).
		Group(dao.AdminDepartment.Columns().DepartId).
		Scan(&peopleRows)
	if err != nil {
		return nil, exception.New(`获取部门人数格式错误`)
	}

	// 是否为空
	if len(peopleRows) == 0 {
		return peopleMap, nil
	}

	// 迭代转换为MAP
	for _, item := range peopleRows {
		peopleMap[item.DepartId] = item.Total
	}
	return peopleMap, nil
}

// RemoveAdminDepartByAid 通过管理员ID解除关联部门-适用于，后台编辑管理员，移除部门之后，未添加新部门，后置清理掉部门
func (r *sRbac) RemoveAdminDepartByAid(ctx context.Context, adminId uint) error {
	if adminId == 0 {
		return exception.New(`缺少管理员ID`)
	}
	// 检测是否关联部门-未关联无需删除
	if !r.CheckAdminDepartByAid(ctx, adminId) {
		return nil
	}

	// 移除之前关联模型
	_, err := dao.AdminDepartment.Ctx(ctx).
		Where(dao.AdminDepartment.Columns().AdminId, adminId).
		Delete()
	if err != nil {
		return exception.New(`解除部门关联失败`)
	}
	return nil
}

// GetDepartmentIdByAid 通过管理员ID获取部门ID
func (r *sRbac) GetDepartmentIdByAid(ctx context.Context, aid ...uint) ([]uint, error) {
	if len(aid) == 0 {
		return nil, exception.New(`管理员ID不存在`)
	}
	// 获取关联列表
	rows, err := r.ProcessAdminIdAndDepartIdList(ctx, g.Map{
		dao.AdminDepartment.Columns().AdminId: aid,
	})
	if err != nil {
		return nil, err
	}

	// 获取部门ID
	return utils.NewArray(rows).ArrayColumnsUniqueUnit(dao.AdminDepartment.Columns().AdminId), nil
}
